package web.admin.shop.product.tabs;

import domain.ImageEntry;
import domain.shop.Product;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.upload.FileUpload;
import org.apache.wicket.markup.html.form.upload.FileUploadField;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import service.ImageService;
import service.facade.admin.ShopAdminService;
import web.admin.config.DirectoryPathException;
import web.commons.ImagePanel;

import java.util.ArrayList;
import java.util.List;

/**
 * Provide uploading files
 */
public final class UploadPanel extends Panel {

    @SpringBean
    private ShopAdminService shopAdminService;
    @SpringBean
    private ImageService imageService;
    private static final Log log = LogFactory.getLog(UploadPanel.class);
    private Long productId;

//    /**
//     * Constructor for stand-alone usage
//     */
//    public UploadPanel(String id) {
//        super(id);
//        productLoading = false;
//        init();
//        choiceForm.setVisible(false);
//        LoadableDetachableModel<List<ImageEntry>> imageList =
//                new LoadableDetachableModel<List<ImageEntry>>() {
//
//                    @Override
//                    protected List<ImageEntry> load() {
//                        return imageService.findAllImages();
//                    }
//                };
//
//        ImageListView imageListView = new ImageListView("images", imageList);
//        add(imageListView);
//
//    }

    /**
     * Constructor for edit products at admin menu
     *
     * @param productId
     */
    public UploadPanel(String id, final Long productId) {
        super(id);
        this.productId = productId;
        // Create feedback panels
        final FeedbackPanel uploadFeedback = new FeedbackPanel("uploadFeedback");
        // Add uploadFeedback to the page itself
        add(uploadFeedback);
        this.productId = productId;
        final IModel<ImageBean> mainImageBeanModel = new LoadableDetachableModel<ImageBean>() {

            @Override
            protected ImageBean load() {
                ImageBean bean = null;
                try {
                    ImageEntry image = shopAdminService.findProductById(productId).getMainImage();
                    bean = new ImageBean(image.getName(), image.getId());
                } catch (Exception e) {
                    log.error(e);
                }
                return bean;
            }
        };

        // Add simple upload form, which is hooked up to its feedback panel by
        // virtue of that panel being nested in the form.
        final FileUploadForm simpleUploadForm = new FileUploadForm("simpleUpload");

        add(simpleUploadForm);
        Form choiceForm = new Form("choiceForm") {

            @Override
            protected void onSubmit() {
                try {
                    shopAdminService.setProductMainImage(productId, mainImageBeanModel.getObject().getImageId());
                } catch (Exception e) {
                    log.error(e);
                    error(getLocalizer().getString("system.error", this));
                }
            }

            {
                IModel<List<ImageBean>> imagesListModel = new LoadableDetachableModel<List<ImageBean>>() {

                    @Override
                    protected List<ImageBean> load() {
                        List<ImageEntry> images = null;
                        try {
                            images = shopAdminService.findProductById(productId).getImages();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        List<ImageBean> imageBeans = new ArrayList<ImageBean>();
                        if (images != null) {
                            for (ImageEntry image : images) {
                                imageBeans.add(new ImageBean(image.getName(), image.getId()));
                            }
                        }
                        return imageBeans;
                    }
                };
                DropDownChoice<ImageBean> dropDownChoice = new DropDownChoice<ImageBean>("imagesDropDown",
                        mainImageBeanModel, imagesListModel, new ChoiceRenderer<ImageBean>("imageName", "imageId"));
                add(dropDownChoice);
            }
        };
        add(choiceForm);


        ImageListView imageListView = new ImageListView("images", productId);
        add(imageListView);
    }


    private class ImageBean {

        private String imageName;
        private Long imageId;

        private ImageBean(String imageName, Long imageId) {
            this.imageName = imageName;
            this.imageId = imageId;
        }

        public void setImageId(Long imageId) {
            this.imageId = imageId;
        }

        public void setImageId(String imageId) {
            this.imageId = Long.valueOf(imageId);
        }

        public String getImageName() {
            return imageName;
        }

        public Long getImageId() {
            return imageId;
        }

        public void setImageName(String imageName) {
            this.imageName = imageName;
        }
    }

    private class ImageListView extends ListView<ImageEntry> {

        public ImageListView(String name, final Long productId) {
            super(name);
            IModel<List<ImageEntry>> imageList = new LoadableDetachableModel<List<ImageEntry>>() {

                @Override
                protected List<ImageEntry> load() {
                    Product productById = null;
                    try {
                        productById = shopAdminService.findProductById(productId);
                        return productById.getImages();
                    } catch (Exception e) {
                        return null;
                    }
                }
            };
            setModel(imageList);
        }

        public ImageListView(String name, final IModel<List<ImageEntry>> files) {
            super(name, files);
        }

        @Override
        protected void populateItem(ListItem<ImageEntry> item) {
            item.add(new ImagePanel("image", item.getModel()));
            Label label = new Label("type", item.getModelObject().getContentType());
            item.add(label);
            label = new Label("fileName", item.getModelObject().getFileName());
            item.add(label);
            label = new Label("name", item.getModelObject().getName());
            item.add(label);
            label = new Label("thumbName", item.getModelObject().getThumbName());
            item.add(label);
            label = new Label("date", item.getModelObject().getCreated().toString());
            item.add(label);
        }
    }

    private class FileUploadForm extends Form<Void> {

        private FileUploadField imageFile;

        public FileUploadForm(String name) {
            super(name);

            // set this form to multipart mode (allways needed for uploads!)
            setMultiPart(true);

            // Add one file input field
            add(imageFile = new FileUploadField("fileInput"));

            // Set maximum size to 100K for demo purposes
//            setMaxSize(Bytes.kilobytes(100));
        }

        @Override
        protected void onSubmit() {
            // A dao object that will hold information about the uploaded image.
            ImageEntry imageEntry = null;
            // The FileUpload object that will be provided by wicket that holds info about
            // the file uploaded to the webapp
            FileUpload fupload = imageFile.getFileUpload();
            if (fupload == null) {
                // No image was provided
                error(getLocalizer().getString("upload.fail.onlyImage", this));
                return;
            } else if (fupload.getSize() == 0) {
                error(getLocalizer().getString("upload.fail.emptyImage", this));
                return;
            } else if (!checkContentType(fupload.getContentType())) {
                // checkContentType(String) said that they uploaded a file of the wrong type.
                error(getLocalizer().getString("upload.fail.imageType", this));
                return;
            } else {
                // Create a new dao object and populate it with info about the image
                imageEntry = new ImageEntry();
                imageEntry.setContentType(fupload.getContentType());
                imageEntry.setName(fupload.getClientFileName());
                try {
                    imageEntry = imageService.save(imageEntry, fupload.getInputStream());
                    Product product = shopAdminService.findProductById(productId);

                    shopAdminService.addImageToProduct(product, imageEntry);
                } catch (DirectoryPathException e) {
                    log.error(e);
                    // It'd be nice to have a logger so that we could log the error.
                    error(getLocalizer().getString("system.error.directory", this));
                }
                catch (Exception ioe) {
                    log.error(ioe);
                    // It'd be nice to have a logger so that we could log the error.
                    error(getLocalizer().getString("upload.fail.error", this));
                }
            }
        }
    }


    private static final String[] VALID_CONTENT_TYPES = {
            "image/gif", "image/jpeg", "image/png"
    };

    private boolean checkContentType(String contentType) {
        for (int i = 0; i < VALID_CONTENT_TYPES.length; i++) {
            if (VALID_CONTENT_TYPES[i].equalsIgnoreCase(contentType)) {
                return true;
            }
        }
        return false;
    }


}
